/*******************************************************************************
 * Copyright (c) 2011 EclipseDevX.org and others.
 * 
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at:
 * 
 *     http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/

package org.eclipsedevx.metrics.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 * 
 * @author dcarew
 */
public class MetricsHistory {
    private Map<String, Integer> values = new HashMap<String, Integer>();
    
    public MetricsHistory() {
        
    }
    
    public MetricsHistory(MetricsHistory copy) {
		this.values = new HashMap<String, Integer>(copy.values);
	}

	public void add(String dayCode, int sloc) {
        values.put(dayCode, sloc);
    }

	public int get(String dayCode) {
		return values.get(dayCode);
	}

    public int getMaxVisualValue() {
        int max = 0;
        
        for (Integer i : values.values()) {
            max = Math.max(max, i);
        }
        
        if (max <= 100) {
        	return 100;
        }
        
        int log = (int)Math.floor(Math.log10(max));
        
        for (int i : new int[] { 2, 4, 5, 10} ) {
        	int testMax = (int)Math.round(Math.pow(10, log) * i);
        	
        	if (testMax >= max) {
        		return testMax;
        	}
        }
        
        return max + 100;
    }

    public List<Integer> getDayValues() {
        List<Integer> result = new ArrayList<Integer>();
        
        int lastValue = 0;
        
        for (String dayCode : getDayCodes()) {
        	Integer i = values.get(dayCode);
        	
        	if (i == null) {
        		result.add(lastValue);
        	} else {
        		lastValue = i;
        		
        		result.add(i);
        	}
        }
        
        return result;
    }
    
    private String[] getDayCodes() {
		String startCode = null;
		
		for (String code : values.keySet()) {
			if (startCode == null) {
				startCode = code;
			} else {
				if (code.compareTo(startCode) < 0) {
					startCode = code;
				}
			}
		}
    	
    	if (startCode == null) {
    		return new String[0];
    	}
		
    	String endCode = DayCode.today().getCode();
    	
		DayCode dayCode = new DayCode(startCode);
		
		List<String> codes = new ArrayList<String>();
		
		// TODO: is this dangerous?
		while (true) {
			codes.add(dayCode.getCode());
			
			if (dayCode.getCode().equals(endCode)) {
				break;
			}
			
			dayCode = dayCode.next();
		}
		
		return codes.toArray(new String[codes.size()]);
	}

	public Map<String, Integer> getValues() {
    	return Collections.unmodifiableMap(values);
    }
    
    public static MetricsHistory combine(List<MetricsHistory> histories) {
        // TODO:
    	
    	MetricsHistory history = new MetricsHistory(histories.get(0));
    	
    	// TODO: if only one value, double it up w/ the day before
        if (history.getValues().size() == 1) {
        	String dayCode = history.getValues().keySet().iterator().next();
        	
        	String prevCode = new DayCode(dayCode).prev().getCode();
        	
        	history.add(prevCode, history.get(dayCode));
        }
    	
        return history;
    }

}
